package com.fhc.base

import android.content.Context
import android.util.Log
import timber.log.Timber
import java.io.File
import java.io.PrintWriter
import java.io.StringWriter
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale


class TimberDebugTree( val tag:String = "")  : Timber.DebugTree(){
    private var element:String = ""
    override fun createStackElementTag(element: StackTraceElement): String {
        val className = element.className.substringAfterLast('.')
        val methodName = element.methodName
        val lineNumber = element.lineNumber
        this@TimberDebugTree.element =  "$className  $methodName $lineNumber"
        return tag.ifEmpty { className }
    }

    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
        val logContent = buildString {
            if (priority == Log.WARN || priority == Log.ERROR)  append("[").append(element).append("]  ").append(message)
            else if (priority == Log.INFO || priority == Log.DEBUG)  append("[DEBUG INFO]").append(message)
        }
        Log.println(priority, tag ?: "Timber", logContent)
    }
}


class TimberReleaseTree(val tag:String = "",  val context: Context, keepDays:Int = 3) : Timber.DebugTree() {
    private val logDir = File("${context.getExternalFilesDir(null)}/logs")
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
    private var retentionDays = 3 // 日志保留天数


    private var element:String = ""
    override fun createStackElementTag(element: StackTraceElement): String {
        val className = element.className.substringAfterLast('.')
//        val methodName = element.methodName
        val lineNumber = element.lineNumber
        this@TimberReleaseTree.element =  "$className $lineNumber"
        return tag.ifEmpty { className }
    }

    init {
        logDir.mkdirs()
        cleanOldLogs() // 初始化时执行清理
        retentionDays = keepDays
    }

    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
        var stackTrace = ""
        var tagExt = "X"
        if (priority == Log.WARN)  tagExt = "W"
        if (priority == Log.ERROR)   tagExt = "E"
        if (priority == Log.ASSERT)   tagExt = "A"
//        if(tag != null)  tagExt = tag + tagExt
        if (priority >= Log.WARN) {
            if(t != null){
                 stackTrace = StringWriter().apply {
                    t.printStackTrace(PrintWriter(this))
                }.toString()
            }
            val logFile = File(logDir, "${dateFormat.format(Date())}.log")
            logFile.appendText("${SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()).format(Date())}  [$tagExt] [$element] $message $stackTrace\n")
        }
    }

    private fun cleanOldLogs() {
        val calendar = Calendar.getInstance().apply {
            add(Calendar.DAY_OF_YEAR, -retentionDays)
        }
        val cutoffDate = calendar.time

        logDir.listFiles()?.forEach { file ->
            try {
                val fileDate = dateFormat.parse(file.nameWithoutExtension)
                if (fileDate != null && fileDate.before(cutoffDate)) {
                    file.delete()
                }
            } catch (e: Exception) {
                Timber.e(e, "Failed to parse log file date")
            }
        }
    }

}
